#pragma once
#include "Sock.hpp"
#include <pthread.h>
#include <vector>
#include <functional>
#include<unistd.h>
namespace tcp_server
{
    using func_t = std::function<void(int)>;
    class TcpServer;
    struct ThreadData
    {
        ThreadData(int sock, TcpServer *server) : sock_(sock), server_(server) {}
        ~ThreadData() {}
        int sock_;
        TcpServer *server_;
    };
    class TcpServer
    {
    private:
        int listensock_;
        Sock sock_;
        std::vector<func_t> func_; // 功能

        static void *ThreadRoutine(void *args)
        {
            pthread_detach(pthread_self());
            ThreadData *td = static_cast<ThreadData *>(args);
            td->server_->Execute(td->sock_);
            close(td->sock_);
            delete td;
            std::cout<<"服务退出"<<std::endl;
            return nullptr;
        }

    public:
        TcpServer(const int16_t &port, const std::string &ip = "0.0.0.0")
        {
            listensock_ = sock_.Socket();
            sock_.Bind(listensock_, port, ip);
            sock_.Listen(listensock_);
        }
        void BindServer(func_t func) // 绑定服务的函数
        {
            func_.push_back(func);
        }
        void Execute(int sock) // 执行服务的函数
        {
            for (auto &f : func_)
            {
                f(sock);
            }
        }
        void Start() // 启动服务
        {
            while (true)
            {
                std::string clientip;
                int16_t clientport;
                int sock = sock_.Accept(listensock_, &clientip, &clientport);
                if (sock == -1)
                {
                    continue;
                }
                logMessage(NORMAL, "create new link success,sock:%d", sock);
                pthread_t tid;
                ThreadData *td = new ThreadData(sock, this);
                pthread_create(&tid, nullptr, ThreadRoutine, td);
            }
        }
        ~TcpServer()
        {
            if (listensock_ >= 0)
                close(listensock_);
        }
    };

}